# -*- coding: utf-8 -*-
"""
文章控制器
目的：处理文章相关的HTTP请求，提供RESTful API端点
职责：接收HTTP请求、参数验证、调用服务层、返回响应
"""
from flask import Blueprint, request, jsonify
from app.services.article_service import ArticleService
from app.utils.auth import token_required, get_current_user
from app.utils.response import bad_request_response, internal_error_response, not_found_response
from app.dto.article_dto import CreateArticleRequest, GetArticlesListRequest


# 创建文章蓝图对象，用于注册文章相关的路由
article_bp = Blueprint('article', __name__, url_prefix='/api/articles')


@article_bp.route('', methods=['POST'])
@token_required
def create_article():
    """
    创建文章API
    目的：处理文章发布请求，验证参数并调用服务层创建文章
    功能：接收文章数据、验证必填字段、调用业务逻辑、返回结果

    请求头:
        Authorization: Bearer <token> - JWT认证令牌

    请求体:
    {
        "title": "文章标题",           // 必填，字符串，最长255字符
        "content": "文章内容",         // 必填，字符串，支持HTML/Markdown
        "summary": "文章摘要",         // 必填，字符串，文章简介
        "category_id": 1,              // 必填，整数，分类ID
        "tags": "标签1,标签2",         // 必填，字符串，逗号分隔
        "cover_image": "图片路径",     // 可选，字符串，封面图片路径
        "location_id": 1,              // 可选，整数，地理位置ID
        "status": 1                    // 可选，整数，0-草稿，1-已发布（默认）
    }

    响应:
    {
        "success": true,
        "message": "文章发布成功",
        "data": {
            "id": 1,
            "title": "文章标题",
            "content": "文章内容",
            "summary": "文章摘要",
            "author_id": 1,
            "category_id": 1,
            "tags": ["标签1", "标签2"],
            "cover_image": "图片路径",
            "location_id": 1,
            "view_count": 0,
            "like_count": 0,
            "comment_count": 0,
            "status": 1,
            "is_top": 0,
            "published_at": "2025-10-01T12:00:00",
            "created_at": "2025-10-01T12:00:00",
            "updated_at": "2025-10-01T12:00:00"
        }
    }
    """
    try:
        # 获取当前登录用户信息，从JWT令牌中解析
        current_user = get_current_user()

        # 解析请求体中的JSON数据
        data = request.get_json()

        if not data:
            return bad_request_response('请求数据格式错误')

        # 提取必填字段
        title = data.get('title')
        content = data.get('content')
        summary = data.get('summary')
        category_id = data.get('category_id')
        tags = data.get('tags')

        # 验证必填字段
        if not all([title, content, summary, category_id, tags]):
            return bad_request_response('文章标题、内容、摘要、分类和标签均为必填项')

        # 提取可选字段
        cover_image = data.get('cover_image')  # 封面图片路径，可选
        location_id = data.get('location_id')  # 地理位置ID，可选
        status = data.get('status', 1)  # 文章状态，默认为1（已发布）

        # 验证status字段的取值范围
        if status not in [0, 1, 2]:
            return bad_request_response('文章状态参数错误，必须为0(草稿)、1(已发布)或2(下线)')

        # 创建请求对象，封装所有参数
        article_request = CreateArticleRequest(
            author_id=current_user.id,
            title=title,
            content=content,
            summary=summary,
            category_id=category_id,
            tags=tags,
            cover_image=cover_image,
            location_id=location_id,
            status=status
        )

        # 调用服务层创建文章，传入请求对象，返回Result对象
        result = ArticleService.create_article(article_request)

        # 直接返回Result对象的响应，HTTP状态码由Result决定
        return result.to_response()

    except Exception as e:
        # 捕获所有异常，返回500错误
        return internal_error_response(f'服务器内部错误：{str(e)}')


@article_bp.route('', methods=['GET'])
def get_articles():
    """
    获取文章列表API（分页）
    目的：查询文章列表，支持多种筛选条件和分页功能
    功能：根据分类、状态、作者、关键词等条件筛选文章，返回分页数据

    查询参数:
        page (int): 可选，页码，从1开始，默认1
        page_size (int): 可选，每页数量，默认10，最大100
        category_id (int): 可选，分类ID筛选
        status (int): 可选，文章状态筛选，0-草稿，1-已发布，2-下线
        author_id (int): 可选，作者ID筛选
        keyword (str): 可选，关键词搜索，搜索标题和摘要
        is_top (int): 可选，是否置顶筛选，0-否，1-是

    响应:
    {
        "success": true,
        "message": "获取文章列表成功",
        "data": {
            "articles": [文章列表，不包含完整内容],
            "total": 总记录数,
            "page": 当前页码,
            "page_size": 每页数量,
            "total_pages": 总页数
        }
    }
    """
    try:
        # 从查询参数获取分页参数
        page = request.args.get('page', 1, type=int)
        page_size = request.args.get('page_size', 10, type=int)

        # 从查询参数获取筛选条件
        category_id = request.args.get('category_id', type=int)
        status = request.args.get('status', type=int)
        author_id = request.args.get('author_id', type=int)
        keyword = request.args.get('keyword', type=str)
        is_top = request.args.get('is_top', type=int)

        # 创建请求对象，封装所有查询参数
        list_request = GetArticlesListRequest(
            page=page,
            page_size=page_size,
            category_id=category_id,
            status=status,
            author_id=author_id,
            keyword=keyword,
            is_top=is_top
        )

        # 调用服务层获取文章列表，传入请求对象，返回Result对象
        result = ArticleService.get_articles_list(list_request)

        # 直接返回Result对象的响应
        return result.to_response()

    except Exception as e:
        return internal_error_response(f'获取文章列表失败：{str(e)}')


@article_bp.route('/<int:article_id>', methods=['GET'])
def get_article(article_id):
    """
    获取文章详情API
    目的：根据文章ID查询文章完整信息
    功能：查询文章并增加浏览次数

    路径参数:
        article_id (int): 文章ID

    响应:
    {
        "success": true,
        "message": "获取文章成功",
        "data": {文章完整信息}
    }
    """
    try:
        # 调用服务层获取文章，同时增加浏览次数，返回Result对象
        result = ArticleService.get_article_by_id(article_id, increment_view=True)

        # 直接返回Result对象的响应
        return result.to_response()

    except Exception as e:
        return internal_error_response(f'获取文章失败：{str(e)}')


@article_bp.route('/categories', methods=['GET'])
def get_categories():
    """
    获取分类列表API
    目的：查询所有可用的文章分类，用于发布文章时选择
    功能：返回启用状态的分类列表，按排序字段排序

    查询参数:
        status (int): 可选，分类状态筛选，1-启用，0-禁用，不传则只返回启用的分类

    响应:
    {
        "success": true,
        "message": "获取分类列表成功",
        "data": [
            {
                "id": 1,
                "name": "技术分享",
                "description": "技术相关的文章",
                "parent_id": null,
                "sort_order": 1,
                "status": 1,
                "created_at": "2025-10-01T12:00:00",
                "updated_at": "2025-10-01T12:00:00"
            },
            ...
        ]
    }
    """
    try:
        # 从查询参数获取状态筛选条件，默认只返回启用的分类
        status = request.args.get('status', 1, type=int)

        # 调用服务层获取分类列表，返回Result对象
        result = ArticleService.get_categories_list(status=status)

        # 直接返回Result对象的响应
        return result.to_response()

    except Exception as e:
        return internal_error_response(f'获取分类列表失败：{str(e)}')


@article_bp.route('/<int:article_id>', methods=['PUT'])
@token_required
def update_article(article_id):
    """
    更新文章API
    目的：处理文章编辑请求，支持部分字段更新
    功能：接收更新数据、权限验证、调用服务层更新文章

    请求头:
        Authorization: Bearer <token> - JWT认证令牌

    路径参数:
        article_id (int): 文章ID

    请求体（所有字段可选）:
    {
        "title": "更新后的标题",
        "content": "更新后的内容",
        "summary": "更新后的摘要",
        "category_id": 2,
        "tags": "新标签1,新标签2",
        "cover_image": "新图片路径",
        "location_id": 2,
        "status": 1,
        "is_top": 0
    }

    响应:
    {
        "code": 200,
        "message": "文章更新成功",
        "data": {更新后的文章完整信息}
    }
    """
    try:
        # 获取当前登录用户信息
        current_user = get_current_user()

        # 解析请求体中的JSON数据
        data = request.get_json()

        if not data:
            return bad_request_response('请求数据格式错误')

        # 提取可选字段
        title = data.get('title')
        content = data.get('content')
        summary = data.get('summary')
        category_id = data.get('category_id')
        tags = data.get('tags')
        cover_image = data.get('cover_image')
        location_id = data.get('location_id')
        status = data.get('status')
        is_top = data.get('is_top')

        # 调用服务层更新文章
        result = ArticleService.update_article(
            article_id=article_id,
            author_id=current_user.id,
            title=title,
            content=content,
            summary=summary,
            category_id=category_id,
            tags=tags,
            cover_image=cover_image,
            location_id=location_id,
            status=status,
            is_top=is_top
        )

        # 返回Result对象的响应
        return result.to_response()

    except Exception as e:
        return internal_error_response(f'更新文章失败：{str(e)}')


@article_bp.route('/<int:article_id>', methods=['DELETE'])
@token_required
def delete_article(article_id):
    """
    删除文章API
    目的：处理文章删除请求，支持软删除和强制删除
    功能：权限验证、调用服务层删除文章

    请求头:
        Authorization: Bearer <token> - JWT认证令牌

    路径参数:
        article_id (int): 文章ID

    查询参数:
        force (int): 可选，是否强制删除，1-物理删除，0或不传-软删除

    响应:
    {
        "code": 200,
        "message": "文章已下线" 或 "文章删除成功"
    }
    """
    try:
        # 获取当前登录用户信息
        current_user = get_current_user()

        # 获取是否强制删除的参数
        force = request.args.get('force', 0, type=int)

        # 调用服务层删除文章
        result = ArticleService.delete_article(
            article_id=article_id,
            author_id=current_user.id,
            force=bool(force)
        )

        # 返回Result对象的响应
        return result.to_response()

    except Exception as e:
        return internal_error_response(f'删除文章失败：{str(e)}')
